<?php
/**
 * 缓存类
 *
 * @copyright Copyright (c) 2008 www.eefocus.com
 * @author kokko<kokko313@gmail.com>
 * @package com
 * @subpackage eefocus
 * @version 1.0 2008-3-21
 */
 class Cache{
	 /**
	 * 缓存默认过期时间
	 *
	 * @access protected
	 * @var interge
	 */
	protected $_expire;  

	/**
	 * 缓存默认路径
	 *
	 * @access protected
	 * @var string
	 */
	protected $_path;
	
	/**
	 * 取得缓存实例化对象
	 *
	 * @static
	 * @access public
	 * @return object
	 */
	public static function getInstance(){
		static $cache = null;
		if( $cache==null ){
			$param = func_get_args();
			if( !empty( $param[0] ) ){
				$type = $param[0];
			}else{
				$type = conf('DATA_CACHE_TYPE');
			}
			$configure['path'] = conf( 'DATA_CACHE_PATH' );
			$configure['expire'] = conf( 'DATA_CACHE_EXPIRE' );
			if( $type=='FILE' )
				$type = 'Cache';
			$cache = new $type( $configure );
		}
		return $cache;
	}

	/**
	 * 根据PHP各种类型变量生成唯一标识号，以便缓存标识
	 *
	 * @param mixed $mix 变量
	 * @return string
	 */
	public static function getUiqMark($mix)
	{
		if(is_object($mix) && function_exists('spl_object_hash')) {
			return spl_object_hash($mix);
		}elseif(is_resource($mix)){
			$mix = get_resource_type($mix).strval($mix);
		}else{
			$mix = serialize($mix);
		}
		return md5($mix);
	}

	/**
	 * 构造函数
	 *
	 * @param string $appName
	 * @param bool $isCache
	 */
	public function __construct( $configure )
    {    
		$this->_path = $configure['path'];
		$this->_expire = $configure['expire'];
    }
	
	/**
     * 读取缓存
	 *
     * @access public 
     * @param string $name 缓存变量名
     * @return mixed
     +----------------------------------------------------------
     */
	public function get( $name,$expire=0 ){
		$filename   =   $this->filename($name);
		if ( !file_exists( $filename ) ) {
           return false;
        }
		if( intval( $expire )>0 ){
			if( time() - filemtime($filename) > $expire ){
				return false;
			}
			$content = @file_get_contents($filename);
		}else{
			$content = @file_get_contents($filename);
			$expire = substr($content,0, 10);
			//当前时间大于有效时间
			if( time()>$expire ){
				 //缓存过期删除缓存文件
                unlink($filename);
				return false;
			}
		}
		$content = $this->decode( substr($content,10 ) );
		return $content;
	}
	
	/**
     * 写入缓存
	 *
     * @access public 
     * @param string $name 缓存变量名
     * @param mixed $value  存储数据
     * @param int $expire  有效时间
     * @return boolen
     */
	public function set( $name,$value,$expire='' ){
		if(empty($expire)) {
        	$expire =  $this->_expire;
        }
		$filename   =   $this->filename($name);
		$data   =   $this->encode($value);
		$data = time()+$expire.$data;
		$result  =   file_put_contents($filename,$data);
		if($result) {
            clearstatcache();
            return true;
        }
        return false;
	}
	
	/**
     * 删除缓存
	 *
     * @access public 
     * @param string $name 缓存变量名
     * @return boolen
     */
	public function del( $name ){
		return @unlink( $this->filename( $name ) );
	}

	/**
     * 清除缓存
	 *
     * @access public 
     * @param string $name 缓存变量名
     * @return boolen
     */
    public function clear()
    {
		import("Files");
        Files::rmdirs( $this->_path.'/' );
    }
	
	/**
     * 取得变量的存储文件名
	 *
     * @access private 
     * @param string $name 缓存变量名
     * @return string
     */
	private function filename( $name ){
		$name = md5($name);
		$subDir = substr( $name,0,5 );
		if( !is_dir( $this->_path.'/'.$subDir ) ){
			import("Files");
			Files::mkdirs( $this->_path.'/'.$subDir );
		}
		$filename = $this->_path.'/'.$subDir.'/'.$name.'.php';
		return $filename;
	}
	
	/**
	 * 将要存入的数据进行处理
	 * 
	 * @access private
	 * @param mix $data;
	 * @return string
	 */
	private function encode($data)
    {
		$data = serialize($data);
		if( function_exists('gzcompress') ){
			//数据压缩
            $data = gzcompress($data,3);
		}
		return $data;
    } 
	
	/**
	 * 将要返回的数据进行处理
	 * 
	 * @access private
	 * @param mix $data;
	 * @return string
	 */
    private function decode($data)
    {	
		//数据压缩
		if( function_exists('gzcompress') ){
			$data = gzuncompress($data);
		}
		return unserialize($data);
    }
}
?>